Vue for


除了vue所提供的v-if指令之外,还提供了另一用于多次渲染元素的模块指令v-for,首先需要提供遍历的元素别名格式为:

1
表达式 is 别名

当然我们也可以使用v-for指令并基于数组来渲染列表,通常items是源数据数组,而item则是被迭代的数组元素别名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<p v-for="item in items" :key="item.message">
{{ item.message }}
</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: [
{message: 'Vue'},
{message: 'Ajax'},
{message: 'Ejs'},
]
}
})
</script>

父作用域属性(第二参数)


v-for块中还支持访问所有父作用域的属性,v-for并支持第二参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="app">
<p v-for="(item, index) in items">
{{title}} - {{index}} - {{ item.message }}
</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
title: 'Hello',
items: [
{message: 'Vue'},
{message: 'Ajax'},
{message: 'Ejs'},
]
}
})
</script>

其中index属性对应的则是输出次数,为v-for所支持的第二参数,其格式为:

1
(表达式 , 表达式二) in 别名 

遍历对象


除了遍历元素之外,for还可以遍历对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<p v-for="item in items">
{{item}}
</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: {
name: 'kun',
age: '10'
}
}
})
</script>

键名:元素


我们可以通过使用vue所提供的另一种方式即键名:元素来循环遍历对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<p v-for="(value ,name) in items">
{{name}}:{{value}}
</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: {
name: 'kun',
age: '10'
}
}
})
</script>

维护状态

v-for渲染元素列表的时候,他会默认使用就地更新的策略,如果数据被改变,vue将不会移动dom元素来匹配数据项的顺序。为了确保他们的每个索引位置正确的渲染

这个时候我们需要为每个节点写入一个唯一的key属性即:

1
2
3
<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>

在官方稳定那个中建议尽可能使用 v-for 时所提供的 key属性,除非遍历输出的DOM内容非常简单,或是希望性能上的提升

数组更新检测

变更方法

ID DA FA
push() 增加一个方法
pop() 从下往上突然的删除一个方法
shift() 从上往下删除一个方法
unshift() 从上方新加入一个方法
splice() splice()方法可用于添加、删除、替换数组内的值
sort() 用于排序方法
reverse() 主要用于排序倒序

sort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<p v-for="item in sortItems">
{{ item }}
</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: [1,20,2,3,4,100],
},
computed: {
sortItems:function() {
return this.items.sort(sortNumber)
}
},
});
function sortNumber(a,b) {
return a-b
}
</script>

reverse()

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<p v-for="item in items.slice().reverse()">
{{ item }}
</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
items: [1,2,3,4,5,6],
}
})
</script>

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

Vue 条件

v-if …… v-if-else …… v-else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<h1 v-if="message === 'Vue'">Vue</h1>
<h1 v-else-if="message === 'Laravel'">Laravel</h1>
<h1 v-else>
不是 Vue 也不是 Laravel
</h1>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
faq: ' ',
message: 'Vue'
}
})
</script>

当地一个条件满足Vue的时候,则自然而然的显示Vue,但如果第一条件不满足但满足了第二条件Laravel,则自然而然的显示Laravel,如果都不满足则输出v-else指令内的信息。

v-if


vue中我们可以通过使用v-if有条件的渲染一块内容,就比如下述code中的message值如果是true则会显示:

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<h1 v-if="message">Vue is awesome!</h1>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
faq: ' ',
message: false
}
})
</script>

v-else

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<h1 v-if="message">Vue is awesome!</h1>
<h1 v-else="message">Hello,world</h1>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
faq: ' ',
message: false
}
})
</script>

如果将message的值为false,那么则显示v-else内的数据,当v-if符合条件则显示其v-if块的信息。

key

复用 key

通过使用key我们可以管理可复用的元素,且vue也会尽可能的提高渲染的效率,使用可服用的元素的好处就是元素不会从头开始进行渲染,这也使得vue变得稍微快一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div id="app">
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
<button @click="toggleLoginType">Toggle login type</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
loginType: 'username'
},
methods: {
toggleLoginType: function () {
return this.loginType = this.loginType === 'username' ? 'email' : 'username'
}
}
})
</script>


在上述code中,我们主要切换了loginType的值,也就是当不满足username条件的时候切换为else块的placeholder,而使得切换效果的功能主要通过v-on进行实现。

唯一 key


复用key的缺点是表单内的信息也会被同步,而如果设置一个唯一的key,则每个数据都是独立的,服用的只是房子本身而并非里面的装饰物:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div id="app">
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email">
</template>
<button @click="leghtLoginType">Toggle login type</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
loginType: 'username'
},
methods: {
leghtLoginType: function () {
return this.loginType = this.loginType === 'username' ? 'email' : 'username'
}
}
})
</script>

v-show


在前端的开发当中我们经常会使用一个非常棒的方法即display,通常当display的值如果为none则不会进行显示。在vue中,v-show主要用于切换display的CSS 属性:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<h1 v-show="show">Hello,Vue</h1>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
show: true
}
})
</script>

当在控制端中执行app.show=false的时候,则此时<h1>标签的css属性将会更改为display: none,则不可见,v-ifv-show的区别可以是:

ID DA
v-if 通过vue进行条件渲染,确保在切换的过程中被销毁和重建
v-show 不管条件如何,元素依然会被显然,只是根据 CSS display 属性进行切换
v-if拥有更高的切换开销,v-show则有更高的初始渲染的开销

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

Vue 计算属性与侦听

计算属性

尽管vue内的表达式非常便利,但设计他们的初衷依然是用于进行简单的运算,如下方的code主要用于翻转字符串:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
{{message.split('').reverse().join('')}}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello,world'
}
})
</script>

但是如果我们想要在模板中多处翻转字符串的时候就会变得非常繁琐,所以对于复杂的处理我们一般使用computed属性,即```所有getter和setter上的this上下文都会被绑定在Vue的实例中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
{{ reversedMessage }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello,world'
},
computed: {
reversedMessage: function() {
return this.message.split('').reverse('').join('')
}
}
})
</script>


在此时,我们首先声明了一个计算属性为reversedMessage,并提供了函数将作特征为 app.reversedMessagegetter函数,同样的我们也可以在控制台中通过使用app.message="vue"来进行修改。

通过计算属性,vue知道app.reversedMessage依赖或引用于app.message所以当app.message发生改变的时候,依赖他的数据自然会被更新。

计算属性和方法

在官方文档中该标题为 计算属性 vs 方法很显然虽然两者最后都会达到同样的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
{{ reversedMessage() }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello,world'
},
methods: {
reversedMessage: function() {
return this.message.split('').reverse().join('')
}
}
})
</script>

但是不同的是计算属性是基于他的响应式依赖进行缓存的,当相关响应式以来发生改变的时候才会重新渲染,所以这就意味着只要````app.message没事不进行该ian,多次访问reversedMessage```并不会立即返回计算之前的效果或再次执行

相比之下与每次访问都要重新进行寻安然,调用方法然后在再次执行函数的操作很明显前者较为优秀。

计算属性和侦听属性

vue为我们提供了一种更加通用的方式来观察响应vue实例上的数据变动即watch的侦听属性,当有一些数据需要随着其他数据进行变动的时候,可以使用watch属性

watch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
var app = new Vue({
el: '#app',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function(val) {
this.fullName = val + '' + this.lastName
},
lastName: function(val) {
this.fullName = this.firstName + '' + val
}
}
})
</script>

computed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
var app = new Vue({
el: '#app',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
computed: {
fullName: function () {
return this.firstName + '' + this.lastName
}
}
})
</script>
ID DA
watch
computed

通过上述的演示我们就可以非常轻松的了解到watch的作用,当很多数据需要随着其他数据改变而改变的时候,这个时候使用watch就非常的适当,而computed对于单个的数据较为有优势。

getter 与 setter

1
2
getter 与 setter
getter 主要用于检索变量,而setter则用于更新变量的值

computed默认用于检索变量,如果想实现于watch差不多的作用那么我们可以增加一下setter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<div id="app">
{{ fullName }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
})
</script>

侦听器


vue为开发者所提供了一种更加丝滑的API为watch,vue在实例化的同时调用watch,来遍历 watch对象内的所有属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<div id="app">
<input v-model="faq">
<p>{{answer}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
faq: ' ',
answer: '请输入信息'
},
watch: {
faq: function(newQuestion, oldQuestion) {
this.answer = '正在输入……'
this.debouncedGetAnswer()
}
},
created: function() {
this.debouncedGetAnswer = _.debounce(this.getAnswer,500)
},
methods: {
getAnswer: function() {
if(this.faq.indexOf('?') === -1) {
this.answer = '输入的时候请加上一个问号'
return
}
this.answer = '正在检索'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function(response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function(error) {
vm.answer = 'API内并没有此数据' + error
})
}
}
})
</script>

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

Vue 模板语法

Vue.js主要使用了基于HTML的模板语法,允许开发者声明式的将DOM绑定至底层的Vue实例数据,由于Vue.js基于HTML模板语法,所以所编写的自然而然能被浏览器所解析(除了远古浏览器)。

插值

插值主要包含了文本、原始HTML、属性、原始表达式等四类,其中我们会在本章一一进行介绍:

文本

Mustache

在Vue.js中,常见的数据绑定形式就使用Mustache语法来进行插值,即<p>{{message}}</p>,这里的Mustache是一款经典的前端模板引擎,而Mustache的价值在其稳定以及经典,其中在Vui内的{{……}}写法就类似与Mustache模板引擎的语法:

1
<p>{{ message }}</p>

v-once

效果
Vue.js为我们提供了一个类似与Object.freeze()阻止修改的方法,而vue又为我们提供了另一种方法即v-once指令,通过v-once指令我们可以进行一次性插值,当数据改变的时候,内容将不会被更新.

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<span v-once>{{ message }}</span>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: 'Hello,world'
}
})
</script>

原始 HTML

通常在为我们提供指令的时候一般都会提供一个输出原始HTML的指令。Vue并不例外,Vue所提供的指令是v-html,即:

1
<div v-html="html"></div>

建议

v-html指令预期是字符串类型,内容按照HTML进行插入,不会被当作vue模板进行编译。使用v-html指令可能会出现一些安全问题,所以我们尽量在一些不容易发生问题的地方使用。

v-bind

v-bind:id


在默认的情况下Mustache语法并不能使用在HTML 属性中(在vue编译的范围内),当遇到这种情况的时候我们可以使用v-bind指令:

1
2
3
4
5
6
7
8
9
<div v-bind:id="app">{{Hello}}</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: 'Hello,world'
}
})
</script>

如果你还不能理解上面的Code以及v-bind指令,我们可以通过下方code来进行理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div v-bind:id="app">{{Hello}}</div>

<div id="app">
<p>{{hello}}</p>
</div>

<script>
var vm = new Vue({
el: "#app",
data: {
message: 'Hello,world'
}
})
</script>

在上述的code中,使用v-bind指令的html属性将会在vue编译的范围内进行输出,而未使用b-bind指令的html属性将不会进行输出。

v-bind:src


通过使用v-bind:src指令,我们可以绑定一个src属性的比如img元素:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<img v-bind:src="img" alt="">
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
img: 'https://img-home.csdnimg.cn/images/20201124032511.png'
}
})
</script>

当然v-bind指令还可以支持缩写为:,及上述img元素重构为:

1
<img :src="img" alt="">

v-pind:class


除了id~src之外,还支持class等方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
.red {
color: red;
}
</style>
<body>
<div id="app">
<p v-bind:class="colorRed">Hello,world</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
colorRed: 'red'
}
})
</script>

Vue 通过class red添加到vue的渲染队列中,最后使用v-pind:class来引入colorRed

v-pind:style

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
.red {
color: red;
}
</style>
<body>
<div id="app">
<p v-bind:style="colorRed">Hello,world</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
colorRed: {
color: 'red',
fontSize: "20px"
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#### v-pind:href
除了以上的几种```v-pind```参数之外,自然还支持了```href```参数
```vue
<div id="app">
<a v-bind:href="url">Go blog</a>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
url: 'http://sif_one.gitee.io/'
}
})
</script>

JavaScript 表达式


vue对javascript表达式有良好的支持,且并不限于表达式,甚至包括语句:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
{{message + ',vue!'}}
</div>
<script>
var app =new Vue({
el: '#app',
data: {
message: 'hello'
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
<div id="app">
{{ ok ? 'YES!' : 'NO!' }}<br>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
ok: false,
}
})
</script>

指令


指令即(Directives)则在vue中则是代表有v-前缀的特殊属性,当表达式改变的时候也会将行为应用到DOM内:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<p v-if="seen">Hello,world!</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
seen: true,
}
})
</script>

由于将属性加入到了DOM对象内,所以我们可以通过控制台来进行操作对象,就如本文中我们将此来实现显示以及隐藏等。

参数


当介绍完指令之后,自然而然的就是轮到了参数,就以上述的code为例子,v-if为属性,而seen为参数,如果要写我们可以这样:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<a v-bind:href="url">Go blog</a>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
url: 'http://sif_one.gitee.io/'
}
})
</script>

修饰符

v-on

1
2
3
4
5
6
7
8
9
10
11
12
13
14
```vue
<div id="app">
</div>
<form v-on:submit.prevent="onSubmit">
<a v-bind:href="url">Go blog</a>
</form>
<script>
var app = new Vue({
el: '#app',
data: {
url: 'http://sif_one.gitee.io/'
}
})
</script>

那么其最后在 v-on指令的笼罩下范围内的<a>标签将会失去原本的作用:

ID DA FA
.stop 调用 event.stopPropagation() 停止传播
.prevent 调用 event.preventDefault() 防止默认
.capture 添加事件侦听器时使用capture(捕获) 模式
.self 只当事件从侦听器绑定元素本身触发时才进行回调
```.{keyCode keyAlias} ``` 只当事件从特定键触发时才进行回调
.native 监听组件根本元素的原生事件
.once 只触发一次回调
.left 只当点击鼠标左键时触发
.right 只当鼠标点击右键时触发
.middle 当鼠标中键时触发
.passive 以 { passive: true } 模式添加侦听器

缩写

虽然已经在上述说明中标注了其指令的缩写,但为了视觉效果和让读者感觉非常重要,还是要单独列一个标题来着重标注

Vue.js最为不同且便捷的方式就是,基本上每个指令都会有一个缩写,其中v-前缀作为一种视觉提示,可用来辨别vue特定的属性,就如本文我们所出现的 v-bindv-on缩写分别为:以及@

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

Vue 实例与 MVVM

MVVM

MVVM是Model-View-ViewModel的缩写,即模型-视图-视图模型,MVVM最早是由微软所提出,主要借鉴了MVC的思想,前端页面中,将模型用Javascript对象表示,View负责显示,而将模型与视图关联起来的叫 ViewModel,ViewModel负责将模型数据同步到视图显示。

如果说到Vue前面为什么要举那么多修改DOM的例子,那无非就是之为读者学习 Vue 实例所铺路,虽然Vue并没有完全的遵守 MVVM模型但是Vue受到了启发。

如果你说jquery与vue来修改DOM节点的区别那么我们可以使用以下例子来进行分别,你会发现vue的确是受到了 MVVM 的启发:

jquery

1
2
var name = 'jquery';
$('#name').text(name);

MVVM

1
2
3
4
5
6
7
8
9
10
11
12
var person = {
name: 'Bart',
};
```
当改变 JavaScript对象的时候,也将会导致DOM结构或数据作出相应的变化,MVVM的出现让我们的从如何操作DOM变成了**如何改变JavaScript**对象数据或状态,这也是MVVM的设计思想之一。

## 创建一个 Vue 实例
Vue的应用创建可以通过 Vueh函数来创建一个新的实例开始,如:
```vue
var vm = new Vue({
// code
})

虽然 Vue并没有完全遵循 MVVM模型,但是其设计也收到了启发,所以在其官方文档中依然会使用vm即(ViewModel)缩写来作为 Vue 的实例。

数据与方法

在Vue实例被创建的时候,他会将 data对象中的所有属性加入到 vue内,当这些属性的值发生改变的时候,试图将会产生一个响应,来匹配更新为新的值:

1
2
3
4
5
6
var vm = new Vue({
el: "#app",
data: {
message: 'Hello,world'
}
})

当这些数据被改变的时候,视图会进行重新渲染

只有当实例被创建的时候就已经存在data中的属性才是响应式的,如果你在控制台内想新添加一个属性,且一开始他为空且不存在,那么将不会触发任何的视图更新,此时需要设置初始值,详情可以查看官方文档内的 : https://vuejs.bootcss.com/guide/instance.html 章节。

当然有了初始值,以及修改的,自然会出现一个组织修改现有属性的方法即Object.freeze(),即:
效果

1
2
3
4
5
6
7
var vm = new Vue({
el: "#app",
data: {
message: 'Hello,world'
}
})
Object.freeze(vm)

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

Vue

Vue 是由尤雨溪所开发的一种前端js框架,以vue为中心的vue 库最为出名,其中知名的有vue-data、vue-table……分别运用在数据大屏以及表格处理方面,其中vue主要用于构建用户界面的渐进式框架,核心库只支持前端显示。而渐进式框架主要是:“一开始不需要完全掌握全部功能,到后面会慢慢的提升”,就以vue-data为例,即使光通过官方文档也可以快速上手,这与vue.js的成功密切相关。

vue.js 的官方文档是写的最为详细的框架文档之一,这与其vue.js发展之出的Laravel 社区文档出现了对比,如果按照通俗的话来讲就是“教你造车但不教你开车”,这也是vue.js如此成功的关键因素之一,其二就是由于vue.js是由国人所开发的,这也增加了vue.js在国内的受欢迎程度不同类框架第一影响更好。

安装

Vue的安装非常的简单,本文主要使用vue所提供的cdn来引入项目内进行演示,vue为开发者提供了两种方式,分别为开发环境版以及生产环境版本,两者的区别就是一个含有了帮助以及命令行警告,而另一个主要优化了尺寸和处理速度,我们分别可以使用以下 CDN进行引入 :

ID DA
开发环境版 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
生产环境版 <script src="https://cdn.jsdelivr.net/npm/vue"></script>

输出

编辑 app.message 值
Vue.js允许使用较为简洁的模板语法以声明式的将数据渲染到HTML DOM(HTML Document Object Model,文档对象模型)内,使得数据可以任意的进行编辑,以及实时预览,HTML DOM用于将元素看作对象,从而使得元素可以被进行编辑以及获取,就比如我们声明一个message对象:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
{{message}}
</div>
<script>
var app =new Vue({
el: '#app',
data: {
message: 'hello,world!'
}
})
</script>

绑定元素属性

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<p v-bind:title="message">绑定标题</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: "绑定属性为toLocaleDateString " + new Date().toLocaleDateString()
}
})
</script>

此时如果将鼠标移动到<p>元素内,则会提示信息为绑定属性为 toLocaleDateString()方法,这里所用到的v-bind为vue所提供的指令:

ID DA FA
v-bind 将这个元素点的标题属性和message 实例内的消息属性 绑定在一起
toLocaleDateString 区域日期字符串
toLocaleTimeString 区域时间字符串
toLocaleString 区域字符串

条件

vue.js支持提交语法的写入,本章主要先介绍下vue的特点以及语法等基础功能的实现,在后续我们会详细介绍vue的条件以及循环指令:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<p v-if="message">Hello,world!</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: true
}
})
</script>

与上述一样,vue不仅仅可以将数据绑定到DOM文本或属性,还可以绑定DOM的结构,这意味着你在控制台中将app.message=false可以将Hello,wirkd!所隐藏。

循环


在vue内,循环可以通过使用v-for指令来实现,与上述一样,vue也会将此绑定到DOM对象内,都可进行控制台内输入app.todos.push({text : "Hello,vue"})进行修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="app">
<ol>
<li v-for="todo in todos">
{{todo.text}}
</li>
</ol>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
todos: [
{ text: 'Hello,world'},
{ text: 'Hello,china'}
]
}
})
</script>

双向绑定

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<p>{{message}}</p>
<input v-model="message">
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: 'Hello,world'
}
})
</script>

通过使用v-model指令,我们可以非常方便的获取表单所输入的内容来实现双向绑定。

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

Jquery mouseover 与 mouseout

淡出与淡退
在 Jquery中,最为常用的是鼠标悬停mouseover以及鼠标移除mouseout,分别可以实现当鼠标悬停时触发的效果以及鼠标移除时所做的动作,本文我们通过配合fadeToggle来实现当鼠标悬停以及鼠标移除时所做的淡出、淡退的效果:

1
2
3
4
5
6
7
8
9
10
<script>
$(document).ready(function () {
$("#issue").mouseover(function () {
$("#issuer").fadeToggle(1000);
});
$("#issue").mouseout(function () {
$("#issuer").fadeToggle(1000);
});
});
</script>

当然如果你觉得消失的太快,也可以设置一下消失方法的停留时间,即mouseout方法下添加setTimeout

1
2
3
4
5
6
7
8
9
10
$(document).ready(function () {
$("#issue").mouseover(function () {
$("#issuer").fadeToggle(1000);
});
$("#issue").mouseout(function () {
setTimeout(function() {
$("#issuer").fadeToggle(1000);
},3000)
});
});

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

JavaScript Promise

Promise 是一种处理异步的代码方式,通过使用Promise使得异步不会陷入回调地狱,而回调地狱主要被比喻成代码看起来层层嵌套的,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})

特点

流程
Promise 对象有主要有两个特点分别为成功(fulfilled)以及失败(rejected),以及初始状态(pending),这也就意味着promise只有当异步结束的时候,才来决定当前处于那个状态,且任何操作都无法进行更改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const fs = require('fs')

const getFile = (fileName) => {
return new Promise((resolve, reject) => {
fs.readFile(fileName, (err, data) => {
if (err) {
const no = "没有该文件"
reject(no)
return
}
resolve(data)
})
})
}

getFile('hellos.text')
.then(data => console.log(data.toString()))
.catch(err => console.error(err))

通过使用Promisifying可以是的 js 函数来接受回调并返回 promise状态,如果文件不存在则调用reject来返回失败,且不会在继续运行,如果文件存在则返回resolve状态并输出文件内容。

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

SVG SMIL Animations

SVG

SVG 是可伸缩矢量图的缩写(Scalable Vector Graphics),是另一种图形格式,通过XML制定行组行,最后由SVG查看器来呈现XML,目前大多数浏览器都可以支持显示SVG。本文中的 Animations在SVG里面,主要用于呈现 SVG 动画效果,而SVG可以实现如下效果:

  1. 基本行组行
  2. 路径形状
  3. 文本
  4. 图片
  5. 分层和透明度
  6. 旋转
  7. 渐变
  8. 链接
  9. 动画制作
  10. 数据用例等

就比如我们来编写一个简单的svg图像:
效果图

1
2
3
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" height="200" width="100" style="stroke: red; fill:royalblue"></rect>
</svg>

svg 图像可以是非常简单也可以是非常复杂,这都将取决与项目的需要来进行改变。就如上述code 中的实例可以看出,我们首先使用了svg标签,之后通过写入rect标签来画一个矩形,设置x,y左边以及大小和轮廓以及填充颜色等。

浏览器使用

在浏览器中我们可以通过使用iframe来引入svg img,通常像是ps、ai等专业级的设计工具都支持导出svg格式:

1
<iframe src="img.svg">

在编写svg的是时候需要注意,所有图像的根元素都是以<svg>所开始的,通常格式为:

1
2
3
4
<svg xmlns = http://www.w3.org/2000/svg
xmlnsxlink = http://www.w3.org/1999/xlink”>
<!-- code -->
</ svg>

svg 分组

svg中,可以通过使用 <g>元素来将svg形状分组在一起,分组后可将单个图形变成一个整体,因此我们可以使用:
分组后的图形整体移动

1
2
3
4
5
6
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="rotate(10 20 40)">
<line x1="10" y1="10" x2="85" y2="10" style="stroke: royalblue;"></line>
<rect x="10" y="20" height="20" width="40" style="stroke: royalblue;"></rect>
</g>
</svg>

动画

动画

1
2
3
4
5
6
7
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<rect x="10" y="20" height="200" width="100" style="stroke: royalblue;">
<animate attributeName="y" form="160" to="160" begin="3s" dur="1s" repeatCount="indefinite"></animate>
</rect>
</g>
</svg>

在SVG动画中,主要基于SMIL即Synchronized Multimedia Integration Language,同步多媒体集成语言来进行实现,通过使用SMIL可以做到动画的移动、颜色、路径运动、元素数值属性等效果。

路径

路径

1
2
3
4
5
6
7
8
9
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<rect x="0" y="0" width="10" height="10" style="stroke: blue;fill: none;">
<animateMotion
path="M10,50 q60,50 100,0 q60,-50 100,0"
begin="0s" dur="10s" repeatCount="indefinite" />
</g>
<path xmlns="http://www.w3.org/2000/svg" d="M10,50 q60,50 100,0 q60,-50 100,0" stroke="#cd0000" stroke-width="2" fill="none"/>
</svg>

SVG Animation的强大之处在于只要是浏览器页面中,使用animation元素,即使在没有css、js的情况下也可以实现,而svg图像可通过使用贝塞尔曲线(bezier curve)进行。

贝塞尔曲线

ID DA
线性贝塞尔曲线(一次) 1
二次贝塞尔曲线 2
三次贝塞尔曲线 3
四次被塞尔曲线 4
五次被塞尔曲线 5

贝塞尔曲线又被称之为济埃曲线,主要应用在二维图形应用程序的数学曲线,一般矢量图形软件通过贝塞尔曲线来精确画出曲线,主要通过线段节点组成:

  1. 节点可通过拖动支点
  2. 线段可进行伸缩

贝塞尔曲线指令

在上述的code直至中,我们主要使用了path元素来写贝塞尔曲线命令,通常Canvas以及CSS3动画函数也会使用贝塞尔曲线,但语法格式会有大多数不同,就比如svg的:

1
<path xmlns="http://www.w3.org/2000/svg" d="M10,50 q60,50 100,0 q60,-50 100,0"/>

通过指令+坐标值进行实现,在svg中,标准的指令值有“10”个,分别为:

ID DA
M 移动到……
Z 关闭路径
L 直线到……
H 水平线到……
V 垂直线到……
C 三次贝塞尔曲线到……
S 光滑三次贝塞尔曲线到……
Q 二次贝塞尔曲线到……
T 光滑贝塞尔曲线到……
A 椭圆弧
R Catumll-Rom 曲线

贝塞尔曲线基础

点
一个标准的贝塞尔曲线当中,主要有四个点,分别为起始点(x)终止点(y)两个曲线点(x1,y1 and x2,y2)
三次贝塞尔曲线
在上图的贝塞尔曲线中的坐标需要组合为svg格式,主要格式为:

  1. M
    1. 211 375
  2. C
    1. x1,y1
      1. 579 294
    2. x2,y2
      1. 209 464
  3. X,Y
    1. 464 384

其表达式为M 211 375 C 579 294, 206 209, 464 384 即 :
效果

1
2
3
<svg xmlns="http://www.w3.org/2000/svg" width='500' height='500'>
<path d='M211 375 C 579 294,206 209, 464 384' style="stroke:blue;stroke-width:1;fill:rgb(238, 238, 238);"></path>
</svg>

最后强烈推荐使用 http://wx.karlew.com/canvas/bezier/ 进行绘制贝塞尔曲线,虽然所生成的code为Canvas格式,但我们依然可以进行提取为CSS或SVG格式的语法

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布

Node.js 异步与回调

在计算机的设计之处,是他都是通过异步来进行的,在此之前我们需要知道异步内的相关类别如:

ID DA
同步 按照需求内的一步一步进行执行
异步 可以同时执行多种事情
堵塞 按照需求内一步一步进行,当一个程序没有执行,下面所排队等待的程序都处于排队状态
非堵塞 当一个程序没有执行完毕,后面所排队的程序都会进行插队

Javascript > node.js

在默认的情况下,javascript都是默认同步执行的,即按照需求内一步一步执行,在node.js之中,由于引入了非堵塞的 I/O环境,所以处理的效率大大提升。

回调

node.js异步内的直接体现就在于回调,而回调就是,当你不知道用户何时会点击按钮,因此你为事件所定义了一个事件的处理程序,该事件会在处理时被触发调用即“回调”。

1
2
3
4
5
server.listen(port, hostname, ()=> {
setTimeout(() => {
console.log(`当前服务运行在 http://${hostname}:${port} 中`);
}, 2000)
})

就比如上述的code中我们指定了sonsole.log会在程序运行的两秒之后执行,通常回调会无处不在,不仅仅在BOM事件中(BOM事件通常与函数结合,函数不会在BOM事件发生前被执行)。

堵塞

堵塞与非堵塞

1
2
3
4
5
6
7
8
9
10
11
12
var fs = require("fs")

var data = fs.readFileSync('hello.text')
fs.readFile('hello.text', (err,data)=> {
if (err != null) {
console.log('没有此文件')
return
}
})

console.log(data.toString())
console.log("程序执行结束!")

输出:

1
2
hello
程序执行结束!

在以上的code中,首先并不存在 hesllo.text 文件,处理回调错误的同时,在node中,任何回调函数中的地一个参数都为错误对象在Node官方文档中被标注为错误优先与回调的说法。

非堵塞

1
2
3
4
5
6
7
8
9
10
var fs = require("fs")

fs.readFile("hello.text", function(err,data) {
if (err !== null) {
console.log(err)
return
}
console.log(data.toString())
})
console.log('程序执行完成')

输出:

1
2
程序执行完成
hello

本文通过堵塞与非堵塞来进行演示,通常情况下堵塞代码是按照需求一步一步的执行,当一个步骤或没有完成时等待的程序处于排队状态,而非堵塞则是不当一步骤没有执行完毕后面所排队的程序都会依次进行插队即处理更加的效率

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布